<template>
  <div class="container">
    姓：<input type="text" v-model="firstName" /><br />
    名：<input type="text" v-model="lastName" /><br />
    全名：<span>{{ fullName }}</span>

    <hr />
    <button @click="changeName">改名字成James-hadeng</button>

    <hr />
    <div>
      <span>Watch情况1：监视【ref】定义的【基本类型】数据</span>
      <h3>当前求和:{{ sum }}</h3>
      <button @click="changeSum">点我sum+1</button>
    </div>

    <hr />
    <div>
      <span>Watch情况2：监视【ref】定义的【对象类型】数据</span>
      <h2>姓名:{{ person.name }}</h2>
      <h2>年龄:{{ person.age }}</h2>
      <button @click="changeName2">修改名字</button>
      <button @click="changeAge2" style="margin: 0 10px">修改年龄</button>
      <button @click="changePerson2">修改整个人</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, watchEffect } from "vue";

let firstName = ref("zhang");
let lastName = ref("san");
let sum = ref(0);
let person = ref({
  name: "james",
  age: 30,
});

/**
 * 这样写的计算属性是只读的。当你计算属性中用到的变量发生变化的时候，就会调用计算属性中的回调函数，
 */
// let fullName = computed(() => {
//   return firstName.value.slice(0, 1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value
// })

// 想要将计算属性变为可读可写可以使用以下方法
let fullName = computed({
  get() {
    return (
      firstName.value.slice(0, 1).toUpperCase() +
      firstName.value.slice(1) +
      "-" +
      lastName.value
    );
  },
  // 这里只会接收1个值，就是传递过来的值
  set(newVal: any) {
    let [newfirstName, newlastName] = newVal.split("-");
    firstName.value = newfirstName;
    lastName.value = newlastName;
    console.log(newVal);
  },
});
function changeName() {
  fullName.value = "James-hadeng";
}

// Watch情况1：监视【ref】定义的【基本类型】数据
function changeSum() {
  sum.value += 1;
}
const stopWatch = watch(sum, (newVal, oldVal) => {
  console.log("sum变化了", "新值" + newVal, "旧值" + oldVal);
  if (sum.value >= 10) stopWatch();
});

// Watch情况2：监视【ref】定义的【对象类型】数据
function changeName2() {
  person.value.name += "~";
}
function changeAge2() {
  person.value.age += 1;
}
function changePerson2() {
  person.value = {
    name: "jordan",
    age: 99,
  };
}

/**
 * 可以写三个参数，第1个参数是监视对象，第二个是函数，第三个是配置对象
 * ### 注意
 *        只有当你监视的对象的地址发生变化的时候，新的值和旧的值才体现出来，当你是改变对象中的某些属性的时候，这时候其实只有一个值，新旧都是一样的。
 *        配置对象，deep开启深度监视模式，就是你可以监视到对象中的某些属性，immediate是否立即监视(上来先执行一边函数，不管是否发生变化)
 */
watch(
  person,
  (newVal, oldVal) => {
    console.log("person发生变化了", newVal, oldVal);
  },
  { deep: true, immediate: true }
);
</script>

<style scoped></style>
